{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mcz50apwZIW1"
      },
      "source": [
        "# SuperGradients Walkthrough Notebook \n",
        "\n",
        "\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "aP5wV3CGnw_a"
      },
      "source": [
        "![SG - Horizontal.png]()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-WOvMdHCZIW5"
      },
      "source": [
        "*Hi there and welcome to SuperGradients, a free open-source training library for PyTorch-based deep learning models.   Let's have a quick look at the SuperGradients library features. The library lets you train models from any Computer Vision tasks or import pre-trained SOTA models, such as object detection, classification of images, and semantic segmentation for videos or images use cases.*\n",
        "\n",
        "*Whether you are a beginner or an expert it is likely that you already have your own training script, model, loss function implementation etc.\n",
        "In this notebook we present the modifications needed in order to launch your training so you can benefit from the various tools the SuperGradients has to offer.*\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3z3T4_Kqmh1G"
      },
      "source": [
        "## \"Wait, but what's in it for me?\"\n",
        "\n",
        "Great question! our short answer is - Easy to use SOTA DL training library.\n",
        "\n",
        "Our long answer - \n",
        "\n",
        "*   Train models from any Computer Vision tasks or import [pre-trained SOTA models](https://github.com/Deci-AI/super-gradients#computer-vision-models-pretrained-checkpoints) (detection, segmentation, and classification - YOLOv5, DDRNet, EfficientNet, RegNet, ResNet, MobileNet, etc.)\n",
        "*  Shorten the training process using tested and proven [recipes](https://github.com/Deci-AI/super-gradients/tree/master/src/super_gradients/recipes) & [code examples](https://github.com/Deci-AI/super-gradients/tree/master/src/super_gradients/examples)\n",
        "*  Easily configure your own or  use plug&play training, dataset , and architecture parameters.\n",
        "*  Save time and easily integrate it into your codebase.\n",
        "\n",
        "\n",
        "\n",
        "\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nDpo1N5QedGw"
      },
      "source": [
        "## Walkthrough Steps:\n",
        "\n",
        "1.  Installations\n",
        "2.  Integrating your dataset\n",
        "3.  Integrating your neural network architecture\n",
        "5.  Integrating your loss function\n",
        "6.  Putting it all together\n",
        "7.  Defining our metrics of evaluation\n",
        "8.  Defining training parameters\n",
        "9.  Training execution\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "iaZtBgZ6kxEM"
      },
      "source": [
        "> **NOTE:** The defult hardware is CPU, if you want to use Google Collab's GPU you need to follow these steps- \n",
        "\n",
        "- Press \"Runtime\" in manu bar\n",
        "- Choose \"Change runtime type\"\n",
        "- Hardware accelerator - choose \"GPU\"\n",
        "- Press \"Save\"\n",
        "- Restart Runtime"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-QkeE2n4dpW_"
      },
      "source": [
        "## Installations"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "8OCzMh8mZIW6"
      },
      "outputs": [],
      "source": [
        "# SuperGradients installation\n",
        "!pip install super-gradients gwpy &> /dev/null\n",
        "\n",
        "# To install from source instead of the last release, comment the command above and uncomment the following one.\n",
        "# !pip install git+https://github.com/Deci-AI/super_gradients.git"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0BQxzIyPZIW8"
      },
      "source": [
        "## **Getting Started With Training a Model**\n",
        "\n",
        "> **NOTE:** All code examples presented in the documentation are in PyTorch framework."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "BPFUvVoTZIW-"
      },
      "source": [
        "### Integrating Your Dataset\n",
        "\n",
        "In order to integrate your own dataset with our training scheme, we introduce the *dataset_interface* concept, which wraps the *torch dataloaders* used for training.\n",
        "The specified dataset interface class must inherit from deci_trainer.trainer.datasets.dataset_interfaces.dataset_interface, which is where data augmentation and data loader configurations are defined.\n",
        "For instance, a dataset interface for Cifar10:\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "o8SiAyKxZIW_",
        "outputId": "283243c4-d5fa-477b-8f47-4e385a7ac088"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "You did not mention an AWS environment.You can set the environment variable ENVIRONMENT_NAME with one of the values: development,staging,production\n",
            "callbacks -WARNING- Failed to import deci_lab_client\n"
          ]
        }
      ],
      "source": [
        "import torchvision.datasets as datasets\n",
        "import torchvision.transforms as transforms\n",
        "from super_gradients.training import utils as core_utils\n",
        "from super_gradients.training.datasets.dataset_interfaces import DatasetInterface\n",
        "\n",
        "\n",
        "class UserDataset(DatasetInterface):\n",
        "\n",
        "    def __init__(self, name=\"cifar10\", dataset_params={}):\n",
        "        super(UserDataset, self).__init__(dataset_params)\n",
        "        self.dataset_name = name\n",
        "        self.lib_dataset_params = {'mean': (0.4914, 0.4822, 0.4465), 'std': (0.2023, 0.1994, 0.2010)}\n",
        "\n",
        "        crop_size = core_utils.get_param(self.dataset_params, 'crop_size', default_val=32)\n",
        "\n",
        "        transform_train = transforms.Compose([\n",
        "            transforms.RandomCrop(crop_size, padding=4),\n",
        "            transforms.RandomHorizontalFlip(),\n",
        "            transforms.ToTensor(),\n",
        "            transforms.Normalize(self.lib_dataset_params['mean'], self.lib_dataset_params['std']),\n",
        "        ])\n",
        "\n",
        "        transform_test = transforms.Compose([\n",
        "            transforms.ToTensor(),\n",
        "            transforms.Normalize(self.lib_dataset_params['mean'], self.lib_dataset_params['std']),\n",
        "        ])\n",
        "\n",
        "        self.trainset = datasets.CIFAR10(root=self.dataset_params.dataset_dir, train=True, download=True,\n",
        "                                         transform=transform_train)\n",
        "\n",
        "        self.valset = datasets.CIFAR10(root=self.dataset_params.dataset_dir, train=False, download=True,\n",
        "                                        transform=transform_test)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "K1lBxRHYZIXA"
      },
      "source": [
        "Required parameters can be passed using the python dataset_params argument. When implementing a dataset interface, the *trainset* and *valset* attributes are required and must be initiated with a torch.utils.data.Dataset type.\n",
        " These fields will cause the SGModel instance to use them accordingly, such as during training, validation, and so on."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wu9BAf96ZIXA"
      },
      "source": [
        "### Integrating Your Neural Network Architecture\n",
        "\n",
        "This is rather straightforward- the only requirement is that the model must be of torch.nn.Module type. In our case, a simple Lenet implementation (taken from https://github.com/icpm/pytorch-cifar10/blob/master/models/LeNet.py)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "IhYX-u74ZIXB"
      },
      "outputs": [],
      "source": [
        "import torch.nn as nn\n",
        "import torch.nn.functional as func\n",
        "\n",
        "\n",
        "class LeNet(nn.Module):\n",
        "    def __init__(self):\n",
        "        super(LeNet, self).__init__()\n",
        "        self.conv1 = nn.Conv2d(3, 6, kernel_size=5)\n",
        "        self.conv2 = nn.Conv2d(6, 16, kernel_size=5)\n",
        "        self.fc1 = nn.Linear(16*5*5, 120)\n",
        "        self.fc2 = nn.Linear(120, 84)\n",
        "        self.fc3 = nn.Linear(84, 10)\n",
        "\n",
        "    def forward(self, x):\n",
        "        x = func.relu(self.conv1(x))\n",
        "        x = func.max_pool2d(x, 2)\n",
        "        x = func.relu(self.conv2(x))\n",
        "        x = func.max_pool2d(x, 2)\n",
        "        x = x.view(x.size(0), -1)\n",
        "        x = func.relu(self.fc1(x))\n",
        "        x = func.relu(self.fc2(x))\n",
        "        x = self.fc3(x)\n",
        "        return x"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8nxcRRZKZIW8"
      },
      "source": [
        "### Integrating Your Loss Function\n",
        "\n",
        "The loss function class must be of torch.nn.module._LOSS type. For example, our CrossEntropyLoss implementation"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "qoxH7RxuZIW9"
      },
      "outputs": [],
      "source": [
        "import torch.nn as nn\n",
        "from super_gradients.training.losses.label_smoothing_cross_entropy_loss import cross_entropy\n",
        "\n",
        "class CrossEntropyLoss(nn.CrossEntropyLoss):\n",
        "    def __init__(self, weight=None, ignore_index=-100, reduction='mean', smooth_eps=None, smooth_dist=None,\n",
        "                 from_logits=True):\n",
        "        super(CrossEntropyLoss, self).__init__(weight=weight,\n",
        "                                                             ignore_index=ignore_index, reduction=reduction)\n",
        "        self.smooth_eps = smooth_eps\n",
        "        self.smooth_dist = smooth_dist\n",
        "        self.from_logits = from_logits\n",
        "\n",
        "    def forward(self, input, target, smooth_dist=None):\n",
        "        if smooth_dist is None:\n",
        "            smooth_dist = self.smooth_dist\n",
        "        loss = cross_entropy(input, target, weight=self.weight, ignore_index=self.ignore_index,\n",
        "                             reduction=self.reduction, smooth_eps=self.smooth_eps,\n",
        "                             smooth_dist=smooth_dist, from_logits=self.from_logits)\n",
        "\n",
        "        return loss"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yH3lYSY5ZIXB"
      },
      "source": [
        "### Putting It All Together\n",
        "\n",
        "We instantiate an Trainer and a UserDatasetInterface, then call *connect_dataset_interface* which will initialize the dataloaders and pass additional dataset parameters to the Trainer instance."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 156,
          "referenced_widgets": [
            "75851debfdce438ebf74134452627a58",
            "b6726d064f33421fae99063f4fc98e3b",
            "abaff283f14a4e5882056412f72bd1ad",
            "ab2afd107a8b4f7a9f1d943dd8215b2b",
            "490cafe5e5084a52b01824d6e1fae44a",
            "621f6549f36b4ffc87f9253cb41984ab",
            "cb644750e8c049c38914b845262727bb",
            "e7ebaa21d5b14abc8d0284ef8555a1aa",
            "aa5da4c9265d4c57b90b754755ad3296",
            "197d340ad08a465787790f4bb2bbf2a5",
            "93e8600dd6844cfbb9a6dd2780bdf1e2"
          ]
        },
        "id": "j07Lm_qnZIXB",
        "outputId": "38c04453-a7c0-4403-e979-945b8447e9ce"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data/cifar-10-python.tar.gz\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "75851debfdce438ebf74134452627a58",
              "version_minor": 0,
              "version_major": 2
            },
            "text/plain": [
              "  0%|          | 0/170498071 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Extracting ./data/cifar-10-python.tar.gz to ./data/\n",
            "Files already downloaded and verified\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/usr/local/lib/python3.7/dist-packages/torch/utils/data/dataloader.py:481: UserWarning: This DataLoader will create 8 worker processes in total. Our suggested max number of worker in current system is 2, which is smaller than what this DataLoader is going to create. Please be aware that excessive worker creation might get DataLoader running slow or even freeze, lower the worker number to avoid potential slowness/freeze if necessary.\n",
            "  cpuset_checked))\n"
          ]
        }
      ],
      "source": [
        "from super_gradients.training import Trainer\n",
        "\n",
        "sg_model = Trainer(experiment_name='LeNet_cifar10_example',ckpt_root_dir=\"/home/data/notebook_ckpts/\")\n",
        "dataset_params = {\"batch_size\": 256}\n",
        "dataset = UserDataset(dataset_params)\n",
        "sg_model.connect_dataset_interface(dataset)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "f8FrhKxMZIXC"
      },
      "source": [
        "Now, we pass a LeNet instance we defined above to the Trainer:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "RbnLARWnZIXC"
      },
      "outputs": [],
      "source": [
        "network = LeNet()\n",
        "sg_model.build_model(network)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RarXWwEcZIXC"
      },
      "source": [
        "Next, we define metrics in order to valuate our model.\n",
        "The metrics objects to be logged during training must be of torchmetrics.Metric type. For more information on how to use torchmetric.Metric objects and implement your own metrics. see https://torchmetrics.readthedocs.io/en/latest/pages/overview.html.\n",
        "During training, the metric's update is called with the model's raw outputs and raw targets. Therefore, any processing of the two must be taken into account and applied in the update.\n",
        "\n",
        "For most of the familiar cases, an existing torchmetric.Metric implementation exists in super_gradients.training.metrics. Here we simply use the SuperGradients Top1 and Top5 accuracy metrics in order to define the metrics for evaluation on the train set and the validation set."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "FAx2nZr9ZIXC"
      },
      "outputs": [],
      "source": [
        "from super_gradients.training.metrics import Accuracy, Top5\n",
        "\n",
        "train_metrics_list = [Accuracy(), Top5()]\n",
        "valid_metrics_list = [Accuracy(), Top5()]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HaQipmc_ZIXD"
      },
      "source": [
        "### Defining Your Training Parameters\n",
        "Finally, we can define the training parameters:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "_fnunu1LZIXD"
      },
      "outputs": [],
      "source": [
        "train_params = {\"max_epochs\": 10,\n",
        "                \"lr_updates\": [100, 150, 200],\n",
        "                \"lr_decay_factor\": 0.1,\n",
        "                \"lr_mode\": \"step\",\n",
        "                \"lr_warmup_epochs\": 0,\n",
        "                \"initial_lr\": 0.1,\n",
        "                \"loss\": CrossEntropyLoss(),\n",
        "                \"criterion_params\": {},\n",
        "                \"optimizer\": \"SGD\",\n",
        "                \"optimizer_params\": {\"weight_decay\": 1e-4, \"momentum\": 0.9},\n",
        "                \"launch_tensorboard\": False,\n",
        "                \"train_metrics_list\": train_metrics_list,\n",
        "                \"valid_metrics_list\": valid_metrics_list,\n",
        "                \"loss_logging_items_names\": [\"Loss\"],\n",
        "                \"metric_to_watch\": \"Accuracy\",\n",
        "                \"greater_metric_to_watch_is_better\": True}\n",
        "                "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "M-Jhp4npkNXT"
      },
      "source": [
        "### Training Execution\n",
        "Now that all of the parameters and integrations are done we can simply call *train*:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "cPRQq43skCeG",
        "outputId": "6c291db3-187d-4eac-93e3-2a1c3d085044"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "sg_model -INFO- Started training for 10 epochs (0/9)\n",
            "\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "Train epoch 0:   0%|          | 0/782 [00:00<?, ?it/s]/usr/local/lib/python3.7/dist-packages/torch/utils/data/dataloader.py:481: UserWarning: This DataLoader will create 8 worker processes in total. Our suggested max number of worker in current system is 2, which is smaller than what this DataLoader is going to create. Please be aware that excessive worker creation might get DataLoader running slow or even freeze, lower the worker number to avoid potential slowness/freeze if necessary.\n",
            "  cpuset_checked))\n",
            "/usr/local/lib/python3.7/dist-packages/torch/cuda/memory.py:386: FutureWarning: torch.cuda.memory_cached has been renamed to torch.cuda.memory_reserved\n",
            "  FutureWarning)\n",
            "Train epoch 0: 100%|██████████| 782/782 [00:25<00:00, 31.23it/s, Accuracy=0.208, Loss=2.08, Top5=0.757, gpu_mem=0.0273]\n",
            "Validation epoch 0: 100%|██████████| 50/50 [00:02<00:00, 20.67it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "base_sg_logger -INFO- Checkpoint saved in /home/data/notebook_ckpts/LeNet_cifar10_example/ckpt_best.pth\n",
            "sg_model -INFO- Best checkpoint overriden: validation Accuracy: 0.22130000591278076\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\n",
            "Train epoch 1: 100%|██████████| 782/782 [00:19<00:00, 39.86it/s, Accuracy=0.222, Loss=2.05, Top5=0.775, gpu_mem=0.0273]\n",
            "Validation epoch 1: 100%|██████████| 50/50 [00:02<00:00, 21.36it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "base_sg_logger -INFO- Checkpoint saved in /home/data/notebook_ckpts/LeNet_cifar10_example/ckpt_best.pth\n",
            "sg_model -INFO- Best checkpoint overriden: validation Accuracy: 0.2540999948978424\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\n",
            "Train epoch 2: 100%|██████████| 782/782 [00:19<00:00, 40.08it/s, Accuracy=0.232, Loss=2.02, Top5=0.788, gpu_mem=0.0273]\n",
            "Validation epoch 2: 100%|██████████| 50/50 [00:02<00:00, 20.90it/s]\n",
            "Train epoch 3: 100%|██████████| 782/782 [00:20<00:00, 38.45it/s, Accuracy=0.229, Loss=2.02, Top5=0.791, gpu_mem=0.0273]\n",
            "Validation epoch 3: 100%|██████████| 50/50 [00:02<00:00, 20.99it/s]\n",
            "Train epoch 4: 100%|██████████| 782/782 [00:19<00:00, 39.73it/s, Accuracy=0.218, Loss=2.06, Top5=0.768, gpu_mem=0.0273]\n",
            "Validation epoch 4: 100%|██████████| 50/50 [00:02<00:00, 21.06it/s]\n",
            "Train epoch 5: 100%|██████████| 782/782 [00:19<00:00, 40.14it/s, Accuracy=0.238, Loss=2.01, Top5=0.791, gpu_mem=0.0273]\n",
            "Validation epoch 5: 100%|██████████| 50/50 [00:02<00:00, 21.09it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "base_sg_logger -INFO- Checkpoint saved in /home/data/notebook_ckpts/LeNet_cifar10_example/ckpt_best.pth\n",
            "sg_model -INFO- Best checkpoint overriden: validation Accuracy: 0.2549999952316284\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\n",
            "Train epoch 6: 100%|██████████| 782/782 [00:19<00:00, 40.08it/s, Accuracy=0.239, Loss=2, Top5=0.799, gpu_mem=0.0273]\n",
            "Validation epoch 6: 100%|██████████| 50/50 [00:02<00:00, 20.94it/s]\n",
            "Train epoch 7: 100%|██████████| 782/782 [00:19<00:00, 39.82it/s, Accuracy=0.237, Loss=1.99, Top5=0.801, gpu_mem=0.0273]\n",
            "Validation epoch 7: 100%|██████████| 50/50 [00:02<00:00, 21.20it/s]\n",
            "Train epoch 8: 100%|██████████| 782/782 [00:19<00:00, 39.91it/s, Accuracy=0.237, Loss=1.99, Top5=0.802, gpu_mem=0.0273]\n",
            "Validation epoch 8: 100%|██████████| 50/50 [00:02<00:00, 20.91it/s]\n",
            "Train epoch 9: 100%|██████████| 782/782 [00:19<00:00, 39.79it/s, Accuracy=0.241, Loss=1.98, Top5=0.803, gpu_mem=0.0273]\n",
            "Validation epoch 9: 100%|██████████| 50/50 [00:02<00:00, 21.22it/s]"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "sg_model -INFO- RUNNING ADDITIONAL TEST ON THE AVERAGED MODEL...\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "\n",
            "Validation epoch 10: 100%|██████████| 50/50 [00:02<00:00, 21.45it/s]\n"
          ]
        }
      ],
      "source": [
        "sg_model.train(train_params)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Y-s4y9-LZIXD"
      },
      "source": [
        "> **Training Parameter Notes:**\n",
        "\\\n",
        "loss_logging_items_names parameter – Refers to the single item returned by our loss function described above.\n",
        "*metric_to_watch* – Is the model’s metric that determines the checkpoint to be saved. In our example, this parameter is set to Accuracy, and can be set to any of the following:\n",
        "A metric name (str) of one of the metric objects from the *valid_metrics_list* or \"Loss\" (which refers to the validation loss).\n",
        "*greater_metric_to_watch_is_better* flag – Determines when to save a model's checkpoint according to the value of the metric_to_watch."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NvaSmNqOfmMr"
      },
      "source": [
        "## Conclusion\n",
        "\n",
        "Great job! You have finished a full walkthrough of SuperGradients components for deep learning models' training. You can now try out our [pre-trained models fine tune notebook](https://colab.research.google.com/drive/1ZR_cvy8tQB_fTZwB2SQxg3RfIVKxNxRO?usp=sharing), or to train your own models using our SOTA models' [recipes](https://github.com/Deci-AI/super-gradients/tree/master/src/super_gradients/recipes)."
      ]
    }
  ],
  "metadata": {
    "accelerator": "GPU",
    "colab": {
      "collapsed_sections": [],
      "name": "SG_Walkthrough.ipynb",
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3 (ipykernel)",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.7.10"
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "75851debfdce438ebf74134452627a58": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HBoxModel",
          "model_module_version": "1.5.0",
          "state": {
            "_view_name": "HBoxView",
            "_dom_classes": [],
            "_model_name": "HBoxModel",
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "box_style": "",
            "layout": "IPY_MODEL_b6726d064f33421fae99063f4fc98e3b",
            "_model_module": "@jupyter-widgets/controls",
            "children": [
              "IPY_MODEL_abaff283f14a4e5882056412f72bd1ad",
              "IPY_MODEL_ab2afd107a8b4f7a9f1d943dd8215b2b",
              "IPY_MODEL_490cafe5e5084a52b01824d6e1fae44a"
            ]
          }
        },
        "b6726d064f33421fae99063f4fc98e3b": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "abaff283f14a4e5882056412f72bd1ad": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_view_name": "HTMLView",
            "style": "IPY_MODEL_621f6549f36b4ffc87f9253cb41984ab",
            "_dom_classes": [],
            "description": "",
            "_model_name": "HTMLModel",
            "placeholder": "​",
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "value": "",
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "description_tooltip": null,
            "_model_module": "@jupyter-widgets/controls",
            "layout": "IPY_MODEL_cb644750e8c049c38914b845262727bb"
          }
        },
        "ab2afd107a8b4f7a9f1d943dd8215b2b": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "FloatProgressModel",
          "model_module_version": "1.5.0",
          "state": {
            "_view_name": "ProgressView",
            "style": "IPY_MODEL_e7ebaa21d5b14abc8d0284ef8555a1aa",
            "_dom_classes": [],
            "description": "",
            "_model_name": "FloatProgressModel",
            "bar_style": "success",
            "max": 170498071,
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "value": 170498071,
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "orientation": "horizontal",
            "min": 0,
            "description_tooltip": null,
            "_model_module": "@jupyter-widgets/controls",
            "layout": "IPY_MODEL_aa5da4c9265d4c57b90b754755ad3296"
          }
        },
        "490cafe5e5084a52b01824d6e1fae44a": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_view_name": "HTMLView",
            "style": "IPY_MODEL_197d340ad08a465787790f4bb2bbf2a5",
            "_dom_classes": [],
            "description": "",
            "_model_name": "HTMLModel",
            "placeholder": "​",
            "_view_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "value": " 170499072/? [00:02&lt;00:00, 93204026.66it/s]",
            "_view_count": null,
            "_view_module_version": "1.5.0",
            "description_tooltip": null,
            "_model_module": "@jupyter-widgets/controls",
            "layout": "IPY_MODEL_93e8600dd6844cfbb9a6dd2780bdf1e2"
          }
        },
        "621f6549f36b4ffc87f9253cb41984ab": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_view_name": "StyleView",
            "_model_name": "DescriptionStyleModel",
            "description_width": "",
            "_view_module": "@jupyter-widgets/base",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.2.0",
            "_model_module": "@jupyter-widgets/controls"
          }
        },
        "cb644750e8c049c38914b845262727bb": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "e7ebaa21d5b14abc8d0284ef8555a1aa": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "ProgressStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_view_name": "StyleView",
            "_model_name": "ProgressStyleModel",
            "description_width": "",
            "_view_module": "@jupyter-widgets/base",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.2.0",
            "bar_color": null,
            "_model_module": "@jupyter-widgets/controls"
          }
        },
        "aa5da4c9265d4c57b90b754755ad3296": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        },
        "197d340ad08a465787790f4bb2bbf2a5": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_view_name": "StyleView",
            "_model_name": "DescriptionStyleModel",
            "description_width": "",
            "_view_module": "@jupyter-widgets/base",
            "_model_module_version": "1.5.0",
            "_view_count": null,
            "_view_module_version": "1.2.0",
            "_model_module": "@jupyter-widgets/controls"
          }
        },
        "93e8600dd6844cfbb9a6dd2780bdf1e2": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_view_name": "LayoutView",
            "grid_template_rows": null,
            "right": null,
            "justify_content": null,
            "_view_module": "@jupyter-widgets/base",
            "overflow": null,
            "_model_module_version": "1.2.0",
            "_view_count": null,
            "flex_flow": null,
            "width": null,
            "min_width": null,
            "border": null,
            "align_items": null,
            "bottom": null,
            "_model_module": "@jupyter-widgets/base",
            "top": null,
            "grid_column": null,
            "overflow_y": null,
            "overflow_x": null,
            "grid_auto_flow": null,
            "grid_area": null,
            "grid_template_columns": null,
            "flex": null,
            "_model_name": "LayoutModel",
            "justify_items": null,
            "grid_row": null,
            "max_height": null,
            "align_content": null,
            "visibility": null,
            "align_self": null,
            "height": null,
            "min_height": null,
            "padding": null,
            "grid_auto_rows": null,
            "grid_gap": null,
            "max_width": null,
            "order": null,
            "_view_module_version": "1.2.0",
            "grid_template_areas": null,
            "object_position": null,
            "object_fit": null,
            "grid_auto_columns": null,
            "margin": null,
            "display": null,
            "left": null
          }
        }
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
